// 导入模块 Import modules
import {
    playerInitData,
    VirtualPlayerDataInterface,
} from '../storage/data/player';
import type { PlayerDataInterface } from '../storage/interface/player';
import { PlayerStorage } from '../storage/storage';

/**
 * @zh 玩家管理器
 * @en Player manager
 * @author Lusisi卢喜喜 <3986410685@qq.com>
 */
class PlayerManager {
    /**
     * @zh 玩家实体
     * @en Player entity
     */
    private entity: GamePlayerEntity;

    /**
     * @zh 初始化玩家管理器
     * @param entity 玩家实体
     * @en Initialize player manager
     * @param entity Player entity
     */
    public constructor(entity: GamePlayerEntity) {
        this.entity = entity;
    }

    /**
     * @zh 初始化玩家数据
     * @en Initialize player data
     */
    public async initData() {
        const data = await PlayerStorage.get(this.entity.player.userId);
        if (!data || !data?.value) {
            await PlayerStorage.set(
                this.entity.player.userId,
                playerInitData(this.entity)
            );
            // @ts-ignore
            this.entity.player.data = (await PlayerStorage.get(
                this.entity.player.userId
            )).value;
        } else {
            // @ts-ignore
            this.entity.player.data = data.value;
            // @ts-ignore
            this.entity.player.data.name = this.entity.player.name;
            // @ts-ignore
            this.entity.player.data.userId = this.entity.player.userId;
        }
    }

    /**
     * @zh 设置玩家数据
     * @example
     * import { PlayerManager } from "@/manager/player";
     * world.onPlayerJoin(({ entity }) => {
     *     PlayerManager.create(entity).setData((data) => {
     *         data.level = 1; // 设置玩家等级为1
     *     });
     * });
     * @en Set player data
     * @example
     * import { PlayerManager } from "@/manager/player";
     * world.onPlayerJoin(({ entity }) => {
     *     PlayerManager.create(entity).setData((data) => {
     *         data.level = 1; // Set player level to 1
     *     });
     * });
     */
    public setData(callback: (data: PlayerDataInterface) => void): void {
        // @ts-ignore
        callback(this.entity.player.data);
    }

    public getData<T>(callback: (data: PlayerDataInterface) => T): T {
        const dataInterface = VirtualPlayerDataInterface;
        const value = callback(dataInterface);
        let key: keyof PlayerDataInterface;
        let name: keyof PlayerDataInterface | undefined;
        for (key in dataInterface) {
            if (dataInterface[key] === value) {
                name = key;
            }
        }
        if (name === undefined) {
            throw Error(
                '传入的对象必须根据回调的data参数进行选择。 ' +
                    'The object passed in must be selected based on `data` of callback.'
            );
        }
        // @ts-ignore
        return this.entity.player.data[name];
    }

    /**
     * @zh 保存玩家数据
     * @en Save player data
     */
    public async saveData() {
        await PlayerStorage.update(
            this.entity.player.userId,
            // @ts-ignore
            this.entity.player.data
        );
    }

    /**
     * @zh 创建管理器实例
     * @param entity 玩家实体
     * @returns 返回管理器对象
     * @en Create manager
     * @param entity Player entity
     * @returns Returns manager object
     */
    public static create(entity: GamePlayerEntity): PlayerManager {
        return new PlayerManager(entity);
    }
}

// 导出模块 Export modules
export { PlayerManager };
